/**
 * Geppetto WebSocket 服务
 * 用于前后端通信
 */

export interface GeppettoMessage {
  type: string;
  status?: string;
  message?: string;
  data?: any;
  error?: string;
  timestamp?: number;
  clientId?: number;
  result?: string;
}

export type MessageHandler = (message: GeppettoMessage) => void;

export class GeppettoWebSocketService {
  private ws: WebSocket | null = null;
  private url: string;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 5;
  private reconnectDelay = 3000;
  private messageHandlers: Map<string, MessageHandler[]> = new Map();
  private isConnecting = false;
  private isConnected = false;

  constructor(url: string = 'ws://localhost:8888/geppetto') {
    this.url = url;
  }

  /**
   * 连接到 WebSocket 服务器
   */
  connect(): Promise<void> {
    return new Promise((resolve, reject) => {
      if (this.isConnected) {
        console.log('WebSocket 已连接');
        resolve();
        return;
      }

      if (this.isConnecting) {
        console.log('WebSocket 正在连接中...');
        return;
      }

      this.isConnecting = true;
      console.log(`连接到 WebSocket: ${this.url}`);

      try {
        this.ws = new WebSocket(this.url);

        this.ws.onopen = () => {
          console.log('✅ WebSocket 连接成功');
          this.isConnected = true;
          this.isConnecting = false;
          this.reconnectAttempts = 0;
          resolve();
        };

        this.ws.onmessage = (event) => {
          try {
            const message: GeppettoMessage = JSON.parse(event.data);
            console.log('📨 收到消息:', message.type, message);
            this.handleMessage(message);
          } catch (error) {
            console.error('解析消息错误:', error);
          }
        };

        this.ws.onclose = () => {
          console.log('❌ WebSocket 连接关闭');
          this.isConnected = false;
          this.isConnecting = false;
          this.ws = null;

          // 尝试重连
          if (this.reconnectAttempts < this.maxReconnectAttempts) {
            this.reconnectAttempts++;
            console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
            setTimeout(() => this.connect(), this.reconnectDelay);
          } else {
            console.error('WebSocket 重连失败，已达到最大重连次数');
          }
        };

        this.ws.onerror = (error) => {
          console.error('❌ WebSocket 错误:', error);
          this.isConnecting = false;
          reject(error);
        };
      } catch (error) {
        console.error('创建 WebSocket 连接错误:', error);
        this.isConnecting = false;
        reject(error);
      }
    });
  }

  /**
   * 断开连接
   */
  disconnect(): void {
    if (this.ws) {
      this.reconnectAttempts = this.maxReconnectAttempts; // 防止自动重连
      this.ws.close();
      this.ws = null;
      this.isConnected = false;
      console.log('WebSocket 已断开');
    }
  }

  /**
   * 发送消息
   */
  send(message: GeppettoMessage): void {
    if (!this.ws || !this.isConnected) {
      console.error('WebSocket 未连接，无法发送消息');
      return;
    }

    try {
      const data = JSON.stringify(message);
      this.ws.send(data);
      console.log('📤 发送消息:', message.type, message);
    } catch (error) {
      console.error('发送消息错误:', error);
    }
  }

  /**
   * 注册消息处理器
   */
  on(messageType: string, handler: MessageHandler): void {
    if (!this.messageHandlers.has(messageType)) {
      this.messageHandlers.set(messageType, []);
    }
    this.messageHandlers.get(messageType)!.push(handler);
  }

  /**
   * 移除消息处理器
   */
  off(messageType: string, handler: MessageHandler): void {
    const handlers = this.messageHandlers.get(messageType);
    if (handlers) {
      const index = handlers.indexOf(handler);
      if (index > -1) {
        handlers.splice(index, 1);
      }
    }
  }

  /**
   * 处理接收到的消息
   */
  private handleMessage(message: GeppettoMessage): void {
    const handlers = this.messageHandlers.get(message.type);
    if (handlers) {
      handlers.forEach(handler => {
        try {
          handler(message);
        } catch (error) {
          console.error(`处理消息 ${message.type} 错误:`, error);
        }
      });
    }

    // 通用处理器
    const allHandlers = this.messageHandlers.get('*');
    if (allHandlers) {
      allHandlers.forEach(handler => {
        try {
          handler(message);
        } catch (error) {
          console.error('通用消息处理器错误:', error);
        }
      });
    }
  }

  /**
   * Ping 服务器
   */
  ping(): void {
    this.send({
      type: 'ping',
      timestamp: Date.now()
    });
  }

  /**
   * 初始化模型
   */
  initModel(): Promise<GeppettoMessage> {
    return new Promise((resolve, reject) => {
      const handler = (message: GeppettoMessage) => {
        this.off('model_initialized', handler);
        this.off('error', errorHandler);
        resolve(message);
      };

      const errorHandler = (message: GeppettoMessage) => {
        this.off('model_initialized', handler);
        this.off('error', errorHandler);
        reject(new Error(message.error || '初始化模型失败'));
      };

      this.on('model_initialized', handler);
      this.on('error', errorHandler);

      this.send({ type: 'init_model' });
    });
  }

  /**
   * 获取网络数据
   */
  getNetwork(): Promise<GeppettoMessage> {
    return new Promise((resolve, reject) => {
      const handler = (message: GeppettoMessage) => {
        this.off('network_data', handler);
        this.off('error', errorHandler);
        resolve(message);
      };

      const errorHandler = (message: GeppettoMessage) => {
        this.off('network_data', handler);
        this.off('error', errorHandler);
        reject(new Error(message.error || '获取网络数据失败'));
      };

      this.on('network_data', handler);
      this.on('error', errorHandler);

      this.send({ type: 'get_network' });
    });
  }

  /**
   * 运行仿真
   */
  runSimulation(): Promise<GeppettoMessage> {
    return new Promise((resolve, reject) => {
      const handler = (message: GeppettoMessage) => {
        this.off('simulation_completed', handler);
        this.off('error', errorHandler);
        resolve(message);
      };

      const errorHandler = (message: GeppettoMessage) => {
        this.off('simulation_completed', handler);
        this.off('error', errorHandler);
        reject(new Error(message.error || '运行仿真失败'));
      };

      this.on('simulation_completed', handler);
      this.on('error', errorHandler);

      this.send({ type: 'run_simulation' });
    });
  }

  /**
   * 获取仿真数据
   */
  getSimulationData(): Promise<GeppettoMessage> {
    return new Promise((resolve, reject) => {
      const handler = (message: GeppettoMessage) => {
        this.off('simulation_data', handler);
        this.off('error', errorHandler);
        resolve(message);
      };

      const errorHandler = (message: GeppettoMessage) => {
        this.off('simulation_data', handler);
        this.off('error', errorHandler);
        reject(new Error(message.error || '获取仿真数据失败'));
      };

      this.on('simulation_data', handler);
      this.on('error', errorHandler);

      this.send({ type: 'get_simulation_data' });
    });
  }

  /**
   * 执行代码
   */
  executeCode(code: string): Promise<GeppettoMessage> {
    return new Promise((resolve, reject) => {
      const handler = (message: GeppettoMessage) => {
        this.off('code_executed', handler);
        this.off('error', errorHandler);
        resolve(message);
      };

      const errorHandler = (message: GeppettoMessage) => {
        this.off('code_executed', handler);
        this.off('error', errorHandler);
        reject(new Error(message.error || '执行代码失败'));
      };

      this.on('code_executed', handler);
      this.on('error', errorHandler);

      this.send({ type: 'execute_code', code });
    });
  }

  /**
   * 检查连接状态
   */
  isWebSocketConnected(): boolean {
    return this.isConnected && this.ws !== null && this.ws.readyState === WebSocket.OPEN;
  }
}

// 创建单例实例
export const geppettoWS = new GeppettoWebSocketService();

